package sf

import "context"

// OrderService 订单服务
type OrderService service

// Receive 收货人信息
type Receive struct {
	UserName    string `json:"user_name"`           // 用户姓名
	UserPhone   string `json:"user_phone"`          // 用户电话
	UserAddress string `json:"user_address"`        // 用户地址
	UserLng     string `json:"user_lng"`            // 用户经度
	UserLat     string `json:"user_lat"`            // 用户纬度
	CityName    string `json:"city_name,omitempty"` //发单城市	用来校验是否跨城；请填写城市的中文名称，如北京市、深圳市
}

// Shop 发货店铺信息
type Shop struct {
	ShopName    string `json:"shop_name"`          //	店铺名称
	ShopPhone   string `json:"shop_phone"`         // 店铺电话
	ShopAddress string `json:"shop_address"`       // 店铺地址
	ShopLng     string `json:"shop_lng,omitempty"` // 店铺经度
	ShopLat     string `json:"shop_lat,omitempty"` // 店铺纬度
}

// ProductDetail 商品详情
type ProductDetail struct {
	ProductName   string `json:"product_name"`             // 物品名称
	ProductID     int    `json:"product_id,omitempty"`     // 物品ID
	ProductNum    int    `json:"product_num"`              // 物品数量
	ProductPrice  int    `json:"product_price"`            // 物品价格
	ProductUnit   string `json:"product_unit,omitempty"`   // 物品单位
	ProductRemark string `json:"product_remark,omitempty"` //备注
	ItemDetail    string `json:"item_detail,omitempty"`    // 详情
}

// OrderDetail 订单详情
type OrderDetail struct {
	TotalPrice     int64           `json:"total_price"`              //用户订单总金额（单位：分）
	ProductType    int             `json:"product_type"`             // 物品类型	枚举值见下面定义
	UserMoney      int64           `json:"user_money,omitempty"`     // 实收用户金额（单位：分）
	ShopMoney      int64           `json:"shop_money,omitempty"`     // 实付商户金额（单位：分）
	WeightGram     int             `json:"weight_gram"`              // 物品重量（单位：克）
	VolumeLitre    int             `json:"volume_litre,omitempty"`   // 物品体积（单位：升）
	DeliveryMoney  int64           `json:"delivery_money,omitempty"` //商户收取的配送费（单位：分）
	ProductNum     uint32          `json:"product_num"`              // 物品个数
	ProductTypeNum int             `json:"product_type_num"`         // 物品种类个数
	ProductDetail  []ProductDetail `json:"product_detail"`           // 物品详情；数组结构，详见product_detail结构
}

// CreateOrderRequest 创建订单请求
type CreateOrderRequest struct {
	DevID            int         `json:"dev_id"`                       // 同城开发者ID
	ShopID           string      `json:"shop_id"`                      // 店铺ID
	ShopType         int         `json:"shop_type,omitempty"`          // 店铺ID类型	1：顺丰店铺ID ；2：接入方店铺ID
	ShopOrderID      string      `json:"shop_order_id"`                // 商家订单号	不允许重复
	OrderSource      string      `json:"order_source"`                 // 订单接入来源	1：美团；2：饿了么；3：百度；4：口碑； 其他请直接填写中文字符串值
	OrderSequence    string      `json:"order_sequence"`               // 取货序号	与order_source配合使用 如：饿了么10号单，表示如下：order_source=2;order_sequence=10。 用于骑士快速寻找配送物
	LbsType          int         `json:"lbs_type"`                     // 坐标类型 1：百度坐标，2：高德坐标
	PayType          int         `json:"pay_type"`                     // 用户支付方式 1：已付款 0：货到付款
	ReceiveUserMoney int         `json:"receive_user_money,omitempty"` // 代收金额	单位：分
	OrderTime        int64       `json:"order_time"`                   // 用户下单时间	秒级时间戳
	IsAppoint        int         `json:"is_appoint"`                   // 是否是预约单	0：非预约单；1：预约单
	AppointType      int         `json:"appoint_type"`                 // 预约单类型	预约单的时候传入,1：预约单送达单；2：预约单上门单
	ExpectTime       int         `json:"expect_time,omitempty"`        // 用户期望送达时间	appoint_type=1时需必传,秒级时间戳
	ExpectPickupTime int         `json:"expect_pickup_time,omitempty"` // 用户期望上门时间	appoint_type=2时需必传,秒级时间戳
	IsInsured        int         `json:"is_insured"`                   // 是否保价，0：非保价；1：保价
	IsPersonDirect   int         `json:"is_person_direct"`             // 是否是专人直送订单，0：否；1：是
	DeclaredValue    int         `json:"declared_value,omitempty"`     // 保价金额	单位：分
	GratuityFee      int         `json:"gratuity_fee,omitempty"`       // 订单小费，不传或者传0为不加小费	单位分，加小费最低不能少于100分
	Remark           string      `json:"remark,omitempty"`             // 订单备注
	RiderPickMethod  int         `json:"rider_pick_method"`            // 物流流向	1：从门店取件送至用户； 2：从用户取件送至门店
	ReturnFlag       int         `json:"return_flag,omitempty"`        // 返回字段控制标志位（二进制）	1:商品总价格，2:配送距离，4:物品重量，8:起送时间，16:期望送达时间，32:支付费用，64:实际支持金额，128:优惠卷总金额，256:结算方式 例如全部返回为填入511
	PushTime         int64       `json:"push_time"`                    // 推单时间	秒级时间戳
	Version          int         `json:"version"`                      // 版本号	参照文档主版本号填写 如：文档版本号1.7,version=17
	Receive          Receive     `json:"receive"`                      // 收货人信息	Obj，详见receive结构
	Shop             *Shop       `json:"shop,omitempty"`               // 发货店铺信息 Obj，详见shop结构， 平台级开发者（如饿了么）需传入 如无特殊说明此字段可忽略
	OrderDetail      OrderDetail `json:"order_detail"`                 // 订单详情	Obj，详见order_detail结构
}

// CreateOrderResponse 创建订单返回
type CreateOrderResponse struct {
	SfOrderID   string `json:"sf_order_id"`   // 顺丰订单号（标准默认为int，可以设置为string）
	SfBillID    string `json:"sf_bill_id"`    // 顺丰运单号（需要设置）
	ShopOrderID string `json:"shop_order_id"` // 商家订单号
	PushTime    int64  `json:"push_time"`     // 推送时间
	//以下字段受请求参数中 return_flag 控制：return_flag中未包含的，此字段将不存在，请注意！
	TotalPrice            int `json:"total_price,omitempty"`             // 配送费总额，当return_flag中包含1时返回，单位分（值为计算出来此单总价）
	DeliveryDistanceMeter int `json:"delivery_distance_meter,omitempty"` // 配送距离，当return_flag中包含2时返回，单位米（值为计算出来实际配送距离）
	WeightGram            int `json:"weight_gram,omitempty"`             // 商品重量，当return_flag中包含4时返回，单位克（值为下单传入参数回传）
	StartTime             int `json:"start_time,omitempty"`              // 起送时间，当return_flag中包含8时返回，时间格式为Unix时间戳，注意转换
	ExpectTime            int `json:"expect_time,omitempty"`             // 期望送达时间，当return_flag中包含16时返回，时间格式为Unix时间戳，注意转换
	TotalPayMoney         int `json:"total_pay_money,omitempty"`         // 支付费用，当return_flag中包含32时返回，单位分
	RealPayMoney          int `json:"real_pay_money,omitempty"`          // 实际支付金额，当return_flag中包含64时返回，单位分（实际支付金额=总金额-优惠卷总金额）
	CouponsTotalFee       int `json:"coupons_total_fee,omitempty"`       // 优惠券总金额，当return_flag中包含128时返回，单位分
	SettlementType        int `json:"settlement_type,omitempty"`         //结算方式，当return_flag中包含256时返回
}

//物品类型product_type枚举值：
//1:快餐
//2:送药
//3:百货
//4:脏衣服收
//5:干净衣服派
//6:生鲜
//7:保单
//8:高端饮品
//9:现场勘验
//10:快递
//12:文件
//13:蛋糕
//14:鲜花
//15:电子数码
//16:服装鞋帽
//17:汽车配件
//18:珠宝
//20:披萨
//21:中餐
//22:水产
//27:专人直送
//32:中端饮品
//33:便利店
//34:面包糕点
//35:火锅
//36:证照
//41:外部落地配
//99:其他

// CreateOrder 创建订单
func (s *OrderService) CreateOrder(ctx context.Context, body *CreateOrderRequest) (*CreateOrderResponse, error) {
	endPoint := "open/api/external/createorder"
	req, err := s.client.NewRequest(endPoint, body)
	if err != nil {
		return nil, err
	}
	resp := new(CreateOrderResponse)
	_, err = s.client.Do(ctx, req, resp)
	if err != nil {
		return nil, err
	}
	return resp, err
}

// CancelOrderRequest 取消订单请求
type CancelOrderRequest struct {
	DevID        int    `json:"dev_id"`                  // api开发者ID
	OrderID      string `json:"order_id"`                // 订单ID
	OrderType    int    `json:"order_type"`              // 查询订单ID类型	1、顺丰订单号 2、商家订单号
	ShopID       string `json:"shop_id,omitempty"`       // 店铺ID	order_type=2时必传shop_id与shop_type
	ShopType     int    `json:"shop_type,omitempty"`     // 店铺ID类型	1、顺丰店铺ID 2、接入方店铺ID
	CancelReason string `json:"cancel_reason,omitempty"` // 取消原因
	PushTime     int    `json:"push_time"`               // 取消时间；秒级时间戳
}

// 取消订单返回
type CancelOrderResponse struct {
	SfOrderID   string `json:"sf_order_id"`   // 顺丰订单号（标准默认为int，可以设置为string）
	ShopOrderID string `json:"shop_order_id"` // 商家订单号
	PushTime    string `json:"push_time"`     // 推送事件
}

// CancelOrder 取消订单
func (s *OrderService) CancelOrder(ctx context.Context, body *CancelOrderRequest) (*CancelOrderResponse, error) {
	endPoint := "open/api/external/cancelorder"
	req, err := s.client.NewRequest(endPoint, body)
	if err != nil {
		return nil, err
	}
	resp := new(CancelOrderResponse)
	_, err = s.client.Do(ctx, req, resp)
	if err != nil {
		return nil, err
	}
	return resp, err
}

// QueryOrderRequest 查询订单请求
type QueryOrderRequest struct {
	DevID     int    `json:"dev_id"`              // api开发者ID
	OrderID   string `json:"order_id"`            // 订单ID
	OrderType int    `json:"order_type"`          // 查询订单ID类型	1、顺丰订单号 2、商家订单号
	ShopID    string `json:"shop_id,omitempty"`   // 店铺ID	order_type=2时必传shop_id与shop_type
	ShopType  int    `json:"shop_type,omitempty"` // 店铺ID类型	1、顺丰店铺ID 2、接入方店铺ID
	PushTime  int    `json:"push_time"`           // 推送时间；秒级时间戳
}

// Feed 顺丰订单状态：1：订单创建 2：订单取消 10：配送员接单 12：配送员到店 15：配送员配送中（已取货） 17：配送员完成订单
type Feed struct {
	SfOrderID     int    `json:"sf_order_id"`   // 顺丰订单号（标准默认为int，可以设置为string）
	ShopOrderID   string `json:"shop_order_id"` // 商家订单号
	OrderStatus   int    `json:"order_status"`
	Operator      string `json:"operator"`
	OperatorName  string `json:"operator_name"`
	OperatorPhone string `json:"operator_phone"`
	StatusDesc    string `json:"status_desc"`
	Content       string `json:"content"`
	CreateTime    string `json:"create_time"`
}

// QueryOrderResponse 查询订单返回
type QueryOrderResponse struct {
	SfOrderID   string `json:"sf_order_id"`   // 顺丰订单号（标准默认为int，可以设置为string）
	ShopOrderID string `json:"shop_order_id"` // 商家订单号
	CreateTime  string `json:"create_time"`   // 订单创建时间
	PushTime    string `json:"push_time"`     // 推送事件
	Feed        []Feed `json:"feed"`          //
}

// QueryOrder 查询订单
func (s *OrderService) QueryOrder(ctx context.Context, body *QueryOrderRequest) (*QueryOrderResponse, error) {
	endPoint := "open/api/external/listorderfeed"
	req, err := s.client.NewRequest(endPoint, body)
	if err != nil {
		return nil, err
	}
	resp := new(QueryOrderResponse)
	_, err = s.client.Do(ctx, req, resp)
	if err != nil {
		return nil, err
	}
	return resp, err
}
